home *** CD-ROM | disk | FTP | other *** search
- #pragma linesize(132) /* listing linewidth = 132 */
-
- /* showhpgl.c */
-
- /* program for reading HP-GL files and plotting to the screen */
- /* copyright 1991, 1992 Robert C. Becker, Lantern Systems */
-
- /* version 1.9
-
- Aug. 18, 1992
-
- Fixed bugs in clip boundaries. Previously, it was possible to draw
- outside the P1/P2 hard clip boundary if IW was set larger than the
- hard clip. Also plotter_units () and user_units () returned the wrong
- values because the wrong corners were saved in the uu_wincorners struct.
- Added solid fill. This required that we access pc_wrt_line () directly
- for acceptable speed and to control pixel overlap. Haven't tried to get
- this out of hatch and cross-hatch fill's. Direct access to the
- hardware required access to mscio.h for constants and some from gstructs.h
- (both part of the graphix library). It's a bit off a kludge, but w/o
- a solid filled rectangle in the library, there is no other choice.
-
- Also cleaned up some code around clipping with P1/P2 reversed. Compensation
- for this case now takes place in the clipping routine, instead of wherever
- clip borders were changed. Much more maintainable.
- */
-
- /* version 1.8
-
- Aug. 8, 1992
-
- Fixed bugs in x-tick and y-tick scaling: were not rescaled when P1/P2
- were changed. IW failed when turned off if scaling was on and P1/P2
- were exchanged. Fixed sign error on uu_2_pux, uu_2_puy when P1/P2
- were exchanged.
-
-
- /* version 1.7
-
- Aug. 3, 1992
-
- Found a bug in isotropic scaling. When no left & bottom parameters are
- supplied, the window is scaled isotropically, but the window is not
- centered. Fixed by rewriting scale () to default left & bottom param's
- to 50% and rewriting set_scale () and plotter_units () to accomodate the
- change.
-
-
- /* version 1.6
-
- July 25, 1992
-
- Fixed bug in graphix.lib (source: graphix.c) which prevented labeling
- lines with no printable characters, but with imbedded control chars (i.e.,
- backspace). Default char scaling at init was relative: HPGL/2 spec calls
- for absolute char sizes at init, but HP7470A and HP7475 plotter manuals
- call for relative char scaling at init. Default char scaling now conforms
- to HPGL/2 spec (SI at IN or DF vs. SR). Default char scaling can be changed
- to relative char sizes by invoking the -70 or -75 flags.
-
- Screen relative char sizes also increased as paper size increased: should
- have stayed the same. Problem traced to the way relative char sizes are
- scaled. Added basis scale factor to adjust for paper size changes.
-
- Discovered bug in drawing when P1/P2 (corner points) are swapped. Bug
- traced to set_scale () routine returning coordinates as if the corners
- were not swapped, but clipping acting as if they were. Fixed. The semantics
- of the way P1 and P2 are displayed on the screen and the way a plotter works
- are different and are more fully explained in showhpgl.doc
-
- Discovered a bug in label directions (DR) when P1/P2 are swapped. Traced
- to compensation for P1/P2 in both label direction setting routine and in
- the scaling routine. Compensation removed from label direction setting
- routine. */
-
- /* version 1.5
-
- completed scaling command (SC) for isotropic scaling with left and
- bottom parameters. Removed some redundant code in scale () and
- plot_size ()
-
- Added debugging switch to turn on error messages when requested. Default
- is no error messages. */
-
-
- /* version 1.1
-
- changes made in video_test () which change the type of information
- returned so that close coordination between different modules is
- eliminated. video_test () now returns a structure pointer which
- contains the adr of the startup structure needed by g_init ().
-
- Also added HP-GL commands:
-
- AH advance half-page
- AF advancd full page
- VA velocity adaptive
- VN velocity normal
-
- as NOP's for backward compatibility with HP9872
- */
-
- /* Notice: HP-GL, HP-GL/2, and HP are registered trademarks of the
- Hewlett-Packard company */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
- #include <dos.h>
- #include <time.h>
- #include "graphix.h"
- #include "hpgl.h"
-
- /* Identifiable graphics adapters and modes are:
-
- CGA_640x200 IBM CGA 640x200 BW
- ATT_640x400 AT&T 640x400, tiny type
- EGA_640x350 IBM EGA high-res 640x350, 16 color
- MCGA_640x480 IBM MCGA high-res 640x480, BW
- VGA_640x480 IBM VGA high-res 640x480, 16 color
-
- This program is linked with autogrph.c to determine the graphics adapter type.
- The user is allowed to select the display type if not satisfied with the
- default selection. This permits the user to examine the effect changing
- resolution has on the resulting display when using compatible displays. */
-
- /*----------------begin external references----------------------*/
-
- extern struct video_type__ display_adapter__ [];
- /* this struct defined in autogrph.c */
- /* array entries contain type, vid_mode, *display */
-
- extern struct _vid_x_parm_ *forced_video [];
- /* defined in getargs.c */
- /* index returned by getargs for video mode references this table */
-
- /*-----------------end external references-----------------------*/
-
- static struct video_display *adapter_types;
- static struct _vid_x_parm_ *video_mode;
-
-
- /* media ranges (maximum plotting range) */
- /* paper size Xmax Ymax size */
- /* ANSI A 10365 7962 8.5 x 11 in. */
- /* ANSI B 16640 10365 11 x 17 in. */
- /* ISO A4 11040 7721 210 x 297 mm */
- /* ISO A3 16153 11040 297 x 420 mm */
-
- struct cplot cp; /* variables for CP instruction */
- struct csizes cs; /* variables for SI & SR instructions */
-
- static struct paper_size ps[] =
- {
- {0.0, 0.0, 11040.0, 7721.0, 9600.0, 7100.0, 11693.0, 8268.0,
- 603.0, 521.0, 10603.0, 7721.0, 0.95284}, /* A4-size */
-
- {0.0, 0.0, 16153.0, 11040.0, 14550.0, 10600.0, 16535.0, 11693.0,
- 170.0, 602.0, 15370.0, 10602.0, 0.65576}, /* A3-size */
-
- {0.0, 0.0, 22915.0, 16153.0, 22450.0, 14550.0, 23386.0, 16535.0,
- 239.0, 1004.0, 21339.0, 16004.0, 0.45764}, /* A2-size: estimated values */
-
- {0.0, 0.0, 32340.0, 22751.0, 31400.0, 22450.0, 33071.0, 23386.0,
- 462.0, 248.0, 31682.0, 21348.0, 0.32448}, /* A1-size: estimated values */
-
- {0.0, 0.0, 45110.0, 33751.0, 44600.0, 32450.0, 46810.0, 33071.0,
- 362.0, 448.0, 44682.0, 33348.0, 0.22773}, /* A0-size: estimated values */
-
- {0.0, 0.0, 10300.0, 7650.0, 8900.0, 7350.0, 11000.0, 8500.0,
- 250.0, 279.0, 10250.0, 7479.0, 1.000}, /* A-size */
-
- {0.0, 0.0, 16640.0, 10365.0, 15000.0, 9850.0, 17000.0, 11000.0,
- 522.0, 259.0, 15722.0, 10259.0, 0.65445}, /* B-size */
-
- {0.0, 0.0, 21365.0, 16640.0, 21050.0, 15000.0, 22000.0, 17000.0,
- 225.0, 1141.0, 21325.0, 16341.0, 0.47378}, /* C-size: estimated values */
-
- {0.0, 0.0, 33640.0, 21365.0, 32300.0, 21050.0, 34000.0, 22000.0,
- 372.0, 233.0, 33522.0, 21333.0, 0.32194}, /* D-size: estimated values */
-
- {0.0, 0.0, 42542, 33344.0, 42300.0, 32300.0, 44000.0, 34000.0,
- 600.0, 600.0, 41944.0, 33250.0, 0.23736} /* E-size: estimated values */
- };
-
- static struct paper_size ps_dp[] =
- {
- {-4860.0, -3600.0, 4860.0, 3600.0, 9600.0, 7100.0, 11693.0, 8268.0,
- -4260.0, -3000.0, 4260.0, 3000.0, 0.95284}, /* A4-size */
-
- {-7320.0, -5340.0, 7320.0, 5340.0, 14550.0, 10600.0, 16535.0, 11693.0,
- -6720.0, 4740.0, 6720.0, 4740.0, 0.65576}, /* A3-size */
-
- {-10800.0, -7800.0, 10800.0, 7800.0, 22450.0, 14550.0, 23386.0, 16535.0,
- -10200.0, -7200.0, 10200.0, 7200.0, 0.45764}, /* A2-size: estimated values */
-
- {-15720.0, -11280.0, 15720.0, 11280.0, 31400.0, 22450.0, 33071.0, 23386.0,
- -15120.0, -10680.0, 15120.0, 10680.0, 0.32448}, /* A1-size: estimated values */
-
- {-22680.0, -16200.0, 22680.0, 16200.0, 44600.0, 32450.0, 46810.0, 33071.0,
- -22080.0, -15600.0, 22080.0, 15600.0, 0.22773}, /* A0-size: estimated values */
-
- {-4508.0, -3718.0, 4508.0, 3718.0, 8900.0, 7350.0, 11000.0, 8500.0,
- -3908.0, -3118.0, 3908.0, 3118.0, 1.000}, /* A-size */
-
- {-7556.0, -4988.0, 7556.0, 4998.0, 15000.0, 9850.0, 17000.0, 11000.0,
- -6956.0, -4388.0, 6956.0, 4388.0, 0.65445}, /* B-size */
-
- {-10096.0, -8036.0, 10096.0, 8036.0, 21050.0, 15000.0, 22000.0, 17000.0,
- -9496.0, -7436.0, 9496.0, 7436.0, 0.47378}, /* C-size */
-
- {-16192.0, -10576.0, 16192.0, 10576.0, 32300.0, 21050.0, 34000.0, 22000.0,
- -15592.0, -9976.0, 15592.0, 9976.0, 0.32194}, /* D-size */
-
- {-21272.0, -16672.0, 21272.0, 16672.0, 42300.0, 32300.0, 44000.0, 34000.0,
- -20672.0, -16072.0, 20672.0, 16072.0, 0.23736} /* E-size */
- };
-
- static struct options *cmd_args;
-
- static void anchor_corn ( FILE * ); /* static fn's defined in this file */
- static void cold_start ( void );
- static void default_coords ( void );
- static void error ( char, char );
- static void fix_anchor ( void );
- static int get_peval ( FILE *, int, int * );
- static void input_p1p2 ( FILE *, int );
- static void iwindow ( FILE * );
- static void plot_line ( FILE *, int );
- static void pe ( FILE * );
- static void pen_down ( FILE * );
- static void pen_up ( FILE * );
- static void plot_size ( FILE *, int );
- static void scale ( FILE * );
- static void select_pen ( FILE *, int );
- static void set_aspect_ratio ( void );
- static void set_defaults ( void );
- static int video_start ( void ); /* autodetect video adapter */
-
- static char copyright [] = "copyright 1991, Robert C. Becker, Lantern Systems";
-
- static int p, init, error_flag, scale_type;
- static int plotmode; /* plotting mode: absolute or relative */
-
- static double clip_xmin, clip_xmax, clip_ymin, clip_ymax;
- static double cr_xpos, cr_ypos, chord_angle, radius;
- static int i_window, plotter;
- static double uux1, uux2, uuy1, uuy2;
- static double iwx1, iwx2, iwy1, iwy2;
- static int pen_map [MAX_COLORS + 1];
-
- struct win_corners uu_wincorner;
- struct clip_border hpgl_clip;
-
- struct fill_anchor
- {
- double x, y, px, py;
- int mode;
- };
-
- static struct fill_anchor anchor; /* anchor corner structure */
-
- double ip1x, ip1y, ip2x, ip2y, ipxsize, ipysize;
- double ipxmin, ipymin, ipxmax, ipymax;
- double psxdef, psydef;
- double uu_2_pux, uu_2_puy; /* user units per plotter unit (x, y) */
- double p1x, p1y, p2x, p2y; /* P1/P2 coordinates */
- double gdu_cm; /* # GDU's per cm */
-
- int scaling; /* scaling flag: ON -> user units: OFF -> plotter units */
- int chord_type; /* type of chord lines drawn: 0 = fixed angle; 1 = adaptive */
- int p_status, symbol_mode; /* pen_status (up/down), symbol mode flag */
- int my_pen; /* mapped pen # */
- char symbol; /* char for symbol mode plots */
- unsigned endlabel; /* end-of-line char for LB */
- int debugging; /* debugging flag */
-
- main (int argc, char **argv)
- {
- double x, y;
- char *s, *t;
- unsigned char c1, c2, ch;
- unsigned l;
- int segs, i, max_pens, video, paper;
- FILE *infile;
-
- cmd_args = getargs (argc, argv);
-
- infile = cmd_args -> infile;
- paper = cmd_args -> paper; /* returns default value of A_paper if not specified */
- video = cmd_args -> video; /* returns default value of 0 if not specified */
- debugging = cmd_args -> debug;
- plotter = (*cmd_args).plotter; /* returns 0 for default, DRAFTPRO otherwise */
-
- if (infile == NULL)
- {
- printf ("Error opening source file\n");
- exit (1);
- }
- if (plotter == DRAFTPRO)
- {
- ip1x = ps_dp[paper].ip1x; /* default paper size is A-size */
- ip1y = ps_dp[paper].ip1y;
- ip2x = ps_dp[paper].ip2x;
- ip2y = ps_dp[paper].ip2y; /* default IP positions */
- ipxmin = ps_dp[paper].ipxmin;
- ipymin = ps_dp[paper].ipymin; /* minimum value for IP coordinates */
- ipxmax = ps_dp[paper].ipxmax;
- ipymax = ps_dp[paper].ipymax; /* maximum value for IP coordinates */
- ipxsize = ps_dp[paper].ipxsize;
- ipysize = ps_dp[paper].ipysize; /* size of paper in 1000th's of an inch */
- psxdef = ps_dp[paper].psxdef;
- psydef = ps_dp[paper].psydef; /* default plot sizes (PS) */
- cs.csize_basis = ps_dp[paper].csize_basis; /* char size basis scale */
- }
- else
- {
- ip1x = ps[paper].ip1x; /* default paper size is A-size */
- ip1y = ps[paper].ip1y;
- ip2x = ps[paper].ip2x;
- ip2y = ps[paper].ip2y; /* default IP positions */
- ipxmin = ps[paper].ipxmin;
- ipymin = ps[paper].ipymin;
- ipxmax = ps[paper].ipxmax;
- ipymax = ps[paper].ipymax; /* maximum value for PS coordinates */
- ipxsize = ps[paper].ipxsize;
- ipysize = ps[paper].ipysize; /* size of paper in 1000th's of an inch */
- psxdef = ps[paper].psxdef;
- psydef = ps[paper].psydef; /* default plot sizes (PS) */
- cs.csize_basis = ps[paper].csize_basis; /* char size basis scale */
- }
-
- if (!video) /* no video option force on command line */
- {
- if ((max_pens = video_start ()) < 1) /* detect and select video adapter & init graphix lib */
- {
- printf ("Unable to detect supported graphix adapter\n");
- exit (1);
- }
- }
- else /* force adapter into specified video mode */
- {
- max_pens = forced_video [video] ->max_pen;
- g_init (forced_video [video]);
- }
-
- pen_map[0] = 0; /* no pen */
-
- for (i = 1; i <= max_pens; ++i) /* build color map: HP colors are the reverse of PC colors */
- pen_map[i] = max_pens - i + 1;
- for (i = max_pens; i <= MAX_COLORS; ++i)
- pen_map[i] = max_pens; /* make all other pen colors white */
-
-
-
- /* some basic limitations to HPGL:
- Plotting area can be scaled from -32768 to 32767. Larger absolute
- values turn off scaling.
- */
-
- csize_mm (); /* set default csize units to mm's */
-
- cold_start (); /* initialize plotter */
- endlabel = ETX; /* default label termination */
- p_status = PENUP;
-
- while ( (c1 = getc (infile)) != (unsigned char) EOF)
- {
- c2 = getc (infile);
- DB (printf ("c1 c2 = %c%c\n", c1, c2);)
- error_flag = 0; /* clear error_flag */
- switch ( tolower ( c1 ) )
- {
- case ESC: /* esc: preceeds RS-232C device control instructions */
- DB (printf ("ESC:\n");)
- if ( c2 != '.')
- {
- print_string ("Unknown escape sequence encountered\n");
- break;
- }
- if (c2 == 'Y' || c2 == 'Z' || c2 == 'B' || c2 == 'E' || c2 == 'J' ||
- c2 == 'K' || c2 == 'L' || c2 == 'O' || c2 == 'R')
- {
- break; /* these commands take no optional arguments */
- }
- if (c2 == '@' || c2 == 'H' || c2 == 'I' || c2 == 'M' || c2 == 'N')
- {
- while ( (c2 = getc (infile)) != ':'); /* kill off characters until terminator */
- break;
- }
- break;
- case 'a': /* aa, ac, ad, af, ah, ap, ar, at */
- switch (tolower (c2))
- {
- case 'a': /* absolute arc */
- abs_arc (infile);
- break;
- case 'c': /* anchor corner */
- anchor_corn ( infile );
- break;
- case 'd': /* alternate font definition */
- print_noinstr ("AD");
- while (get_val (infile, &x)); /* trim off any following values */
- break;
- case 'f': /* af */
- break;
- case 'h': /* advance half-page */
- break;
- case 'p': /* automatic pen: NOP */
- (void) get_val (infile, &x); /* possibly one trailing value */
- break;
- case 'r': /* relative arc */
- rel_arc (infile);
- break;
- case 't': /* 3 point arc, absolute */
- arc_3pt_abs (infile);
- break;
- default: /* illegal instr */
- error (c1, c2);
- }
- break;
- case 'b': /* bp */
- if (tolower (c2) != 'p')
- {
- error (c1, c2);
- break;
- }
- begin_plot (infile); /* bp: begin plot */
- break;
- case 'c': /* ca, cf, ci, cp, cr, cs, ct */
- switch (tolower (c2))
- {
- case 'a': /* designate alternative char set */
- (void) get_val (infile, &x); /* get any trailing character set value */
- print_noinstr ("CA");
- break;
- case 'f': /* character fill mode */
- print_noinstr ("CF");
- while (get_val (infile, &x)); /* collect trailing values, if any */
- break;
- case 'i': /* circle */
- circle (infile);
- break;
- case 'p': /* char plot */
- char_plot (infile);
- break;
- case 'r': /* set color range */
- while (1) /* remove any trailing arguments (should be 6) */
- if (!get_val (infile, &x)) break;
- print_noinstr ("CR");
- break;
- case 's': /* designate standard char set */
- (void) get_val (infile, &x); /* get any trailing argument */
- print_noinstr ("CS");
- break;
- case 't': /* chord tolerance */
- chord_t (infile);
- break;
- default:
- error (c1, c2);
- }
- break;
- case 'd': /* dc, df, di, dl, dp, dr, ds, dt, dv */
- switch (tolower (c2))
- {
- case 'c': break; /* digitize clear: NOP */
- case 'f': set_defaults (); /* set default values */
- break;
- case 'i': label_adir (infile); /* get absolute label direction */
- break;
- case 'l': /* download character */
- while (1) /* remove any trailing arguments (should be 6) */
- if (!get_val (infile, &x)) break;
- print_noinstr ("DL");
- break;
- case 'p': break; /* digitize point: not meaningful here */
- case 'r': label_rdir (infile); /* get relative label direction */
- break;
- case 's': /* designate char. set into slot */
- print_noinstr ("DS");
- for (i = 0; i < 2; ++i) /* trim off up to 2 trailing values */
- if (!get_val (infile, &x)) break;
- break;
-
- case 't': /* define label terminator */
- label_term (infile);
- break;
- case 'v': /* define variable text path */
- define_path (infile);
- break;
- default:
- error (c1, c2);
- }
- break;
- case 'e': /* ea, ec, ep, er, es, ew */
- switch (tolower (c2))
- {
- case 'a': /* edge rectangle absolute */
- edge_rect_abs (infile);
- break;
- case 'c': /* enable cutter */
- (void) get_val (infile, &x); /* trim trailing value */
- break;
- case 'p':
- break;
- case 'r':
- edge_rect_rel (infile);
- break;
- case 's': /* extra space */
- x = 0.0;
- y = 0.0;
- get_val (infile, &x);
- get_val (infile, &y);
- /* get_val returns x, y values unchanged
- and file pointer unchanged if file pointer
- points to non-numeric data */
- extra_space (x, y);
- break;
- case 'w': /* edge wedge */
- draw_wedge (infile);
- break;
- default:
- error (c1, c2);
- }
- break;
- case 'f': /* fi, fn, fp, fr, ft */
- switch (tolower (c2))
- {
- case 'i': print_noinstr ("FI");
- break;
- case 'n': print_noinstr ("FN");
- break;
- case 'p': print_noinstr ("FP");
- break;
- case 'r': print_noinstr ("FR");
- break;
- case 't': fill_type (infile, scaling);
- break;
- default:
- error (c1, c2);
- }
- break;
-
- case 'g': /* gm (DraftPro instruction: allocate graphics memory */
- if (tolower (c2) == 'm')
- {
- for (i = 0; i < 5; ++i) /* up to 5 arguments allowed */
- if (!get_val (infile, &x)) break;
- }
- else
- {
- error (c1, c2);
- }
- break;
-
- case 'i': /* im, in, ip, ir, iw */
- switch (tolower (c2))
- {
- case 'm': /* at least 1 arg, and at most 3 args */
- if ( !get_val (infile, &x)) break;
- if ( !get_val (infile, &x)) break;
- if ( !get_val (infile, &x)) break;
- break;
- case 'n':
- initialize (infile); /* initialize graphics routines */
- break;
- case 'p':
- input_p1p2abs (infile); /* input p1 & p2 coordinates */
- break;
- case 'r':
- input_p1p2rel (infile); /* input P1/P2 relative coordinates */
- break;
- case 'w': /* get corner of clipping window */
- iwindow (infile);
- break;
- default:
- error (c1, c2);
- break;
- }
- break;
-
- case 'l': /* la, lb, lo, lt */
- switch (tolower (c2))
- {
- case 'a': /* line attributes */
- print_noinstr ("LA");
- for (i =0; i < 6; ++i) /* trim off up to 6 trailing values */
- if (!get_val (infile, &x)) break;
- break;
- case 'b': /* lb instr. */
- label_graph (infile);
- break;
- case 'o': /* lo instr. */
- label_origin (infile);
- break;
- case 't': /* lt instr */
- line_pattern (infile);
- break;
- default:
- error (c1, c2);
- }
- break;
-
- case 'm': /* mc, mg, mt */
- switch (tolower (c2))
- {
- case 'c': /* merge control */
- (void) get_val (infile, &x); /* dump trailing value */
- break;
- case 'g': /* message */
- ch = getc (infile);
- while (ch != TERMCHAR && ch != (unsigned char) EOF) ch = getc (infile);
- break; /* dump the entire message */
- case 't': /* media type: ignored */
- (void) get_val (infile, &x);
- break;
- default:
- error (c1, c2);
- }
- break;
- case 'n': /* np, nr */
- switch ( tolower (c2))
- {
- case 'p': /* number of pens */
- break;
- case 'r': /* not ready */
- twait (infile, -1); /* read delay value from stream & wait */
- break;
- default:
- error (c1, c2);
- }
- break;
- case 'o': /* oa, oc, od, oe, of, oh, oi, oo, op, os, ow */
- switch ( tolower (c2))
- {
- case 'a': /* ignore all output instructions */
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'h':
- case 'i':
- case 'o':
- case 'p':
- case 's':
- case 'w': break;
- default:
- error (c1, c2);
- }
- break;
-
- case 'p': /* pa, pc, pd, pe, pg, pm, pr, ps, pu, pw */
- switch ( tolower ( c2 ) )
- {
- case 'a':
- plot_abs (infile);
- break;
- case 'c':
- print_noinstr ("PC");
- for (i =0; i < 4; ++i) /* trim off up to 4 trailing values */
- if (!get_val (infile, &x)) break;
- break;
- case 'd': /* keep track of pen status here */
- pen_down (infile);
- break;
- case 'e':
- pe (infile); /* polyline encoded */
- break;
- case 'g': /* page advance */
- page_adv (infile);
- new_plot (); /* new plot: not plotted on...yet */
- break;
- case 'm': /* polygon mode */
- print_noinstr ("PM");
- get_val (infile, &x);
- break;
- case 'r':
- plot_rel (infile);
- break;
- case 's': /* plot_size */
- plot_size (infile, plotter);
- break;
- case 'u': penup (); /* raise pen */
- pen_up (infile);
- break;
- case 'w': /* pen width */
- print_noinstr ("PW");
- for (i = 0; i < 2; ++i) /* trim off up to 2 trailing values */
- if (!get_val (infile, &x)) break;
- break;
- default:
- error (c1, c2);
- break;
- }
- break;
- case 'q':
- DB (printf ("case 'q', c2 = %c\n", c2);)
- if (tolower (c2) == 'l') /* ql: quality level. NOP */
- {
- (void) get_val (infile, &x); /* dump any trailing value */
- break;
- }
- error (c1, c2); /* unknown instruction */
- break;
- case 'r':
- switch ( tolower (c2) )
- {
- case 'a': /* filled rectangle, absolute */
- filled_rect_abs (infile);
- break;
- case 'f': /* raster fill definition */
- print_noinstr ("RF");
- while (get_val (infile, &x)); /* dump all trailing values */
- break;
- case 'o': /* rotate origin */
- print_noinstr ("RO");
- get_val (infile, &x); /* dump trailing angle value (if any) */
- break;
- case 'p': /* replot */
- get_val (infile, &x); /* dump any trailing value */
- break;
- case 'r': /* filled rectangle, relative */
- filled_rect_rel (infile);
- break;
- case 't': /* edge 3-pt arc, relative */
- arc_3pt_rel (infile);
- break;
- default:
- error (c1, c2); /* illegal instr */
- break;
- }
- break;
- case 's': /* sb, sp, sc, sd, si, sl, sm, sp, sr, ss, st, sv */
- switch ( tolower (c2) )
- {
- case 'a': /* select alternate font */
- print_noinstr ("SA");
- break;
- case 'b': /* scalable or bitmap fonts */
- print_noinstr ("SB");
- break;
- case 'c':
- scale (infile); /* set scale parameters */
- break;
- case 'd': /* standard font definition */
- print_noinstr ("SD");
- break;
- case 'i': /* char size (absolute) */
- set_acsize (infile); /* set char size (in cm) */
- break;
- case 'l': /* char slant */
- set_slant (infile);
- break;
- case 'm': /* symbol mode */
- c2 = getc (infile); /* get next symbol */
- DB (printf ("SM: symbol char = %c (0x%02X)\n", c2, c2);)
- if (c2 == TERMCHAR || c2 == ' ' || iscntrl (c2) || (c2 > 126 && (c2 != 161 || c2 != 254)))
- {
- symbol_mode = 0; /* symbol mode off */
- break;
- }
- symbol = c2;
- symbol_mode = 1; /* turn symbol mode on */
- DB (printf ("symbol mode on\n");)
- break;
- case 'p':
- select_pen (infile, max_pens);
- break;
- case 'r': /* char size (relative) */
- set_rcsize (infile); /* set relative csize */
- break;
- case 's': /* select standard font */
- print_noinstr ("SS");
- break;
- case 't': /* sort vectors: NOP */
- (void) get_val (infile, &x); /* possibly get one parameter */
- break;
- case 'v': /* screened vectors */
- while (1) /* trim off up to 3 trailing values */
- (void) get_val (infile, &x);
- print_noinstr ("SV");
- break;
- default:
- error (c1, c2);
- break;
- }
- break; /* end of case 's' switch */
- case 't': /* td, tl, tr */
- switch (tolower (c2))
- {
- case 'd':
- xparent_data (infile);
- break;
- case 'l':
- tick_length (infile);
- break;
- case 'r':
- print_noinstr ("TR");
- break;
- default:
- error (c1, c2);
- break;
- }
- break;
- case 'u': /* ul */
- if (tolower (c2) != 'l')
- {
- error (c1, c2);
- break;
- }
- print_noinstr ("UL");
- break;
- case 'v': /* vs: not needed for CRT */
- switch (tolower (c2))
- {
- case 'a': /* va */
- break;
- case 'n': /* velocity normal */
- break;
- case 's': /* velocity set */
- velocity_sel (infile);
- break;
- default:
- error (c1, c2);
- break;
- }
- break;
- case 'w': /* wg, wu */
- switch (tolower (c2))
- {
- case 'g': /* wg: filled wedge */
- draw_wedge (infile); /* outline wedge: no filled wedge available */
- break;
- case 'u': /* pen width: not implimented */
- (void) get_val (infile, &x); /* dump value assoc. with instr */
- print_noinstr ("WU");
- break;
- default: error (c1, c2);
- }
- break;
- case 'x': /* xt */
- if (tolower (c2) != 't')
- {
- error (c1, c2);
- break;
- }
- draw_xtick ();
- break;
- case 'y': /* yt */
- if (tolower (c2) != 't')
- {
- error (c1, c2);
- break;
- }
- draw_ytick ();
- break;
- default:
- ungetc (c2, infile); /* in case if trailing trash */
- break;
- }
- if (error_flag) ungetc (c2, infile); /* in case of illegal instruction */
- }
- fclose (infile);
- }
-
- /*--------------------------------------*/
-
- void initialize (FILE * infile) /* graphics setup routine */
- {
- double t; /* trash variable */
-
- DB (printf ("IN: initializing: window set for HP7470A\n");)
-
- (void) get_val (infile, &t); /* check for value (unused) for HPGL/2 compatibility */
- cold_start ();
- return;
- }
-
- /*--------------------------------------*/
-
- static void cold_start ( void ) /* plotter initialization routine */
- {
- double x;
-
-
- default_coords (); /* set default coordinates for plotter */
-
- set_aspect_ratio (); /* activate new hard clip limits */
-
- p_status = PENUP;
- set_defaults (); /* set default plotter conditions */
-
- move (p1x, p1y); /* move to P1 corner of "hard" clip */
- set_anchor (p1x, p1y, scaling); /* anchor corner for fill types */
-
- cp.x = p1x; /* initial values for CP last position */
- cp.y = p1y; /* Leave alone if not initializing */
-
- init_fills (); /* clear previous fill-codes */
-
- new_plot (); /* this plot has not been drawn on, yet */
- return;
- }
-
- /*--------------------------------------*/
-
- static void set_defaults ( void )
- {
- double x1, x2, y1, y2;
-
- symbol_mode = OFF; /* symbol mode is off */
- i_window = OFF; /* input window is off */
- plotmode = PA; /* absolute plotting */
- ldir (0);
- cdir (0); /* reset label direction to horizontal */
- cp.lorg = LORG_DEFAULT; /* default initial label origin */
- cp.dv = 0; /* update stacking direction code to default direction */
- cp.dvdir = 0.0; /* update stacking direction angle (degrees) */
- cp.ldir = 0.0; /* update label direction vector (degrees) */
- cs.slant = 0.0; /* no char. slant */
-
- disp_fns (DFN_OFF); /* display fn's off (TD0) */
- line_type (0, 0);
- chord_type = ANG; /* select chords in angle units */
-
- /* preset default character size & size in current plotter units */
- cs.rcsize_x = 0.75;
- cs.rcsize_y = 1.50; /* character width (x) and height (y) in % of page sizes in X & Y directions */
-
- cs.acsize_x = 0.19;
- cs.acsize_y = 0.27; /* character width (x) & height (y) in cm */
-
- if (plotter == DRAFTPRO || plotter == 0)
- cs.cscale_mode = 0; /* select absolute char size scaling */
- /* set abs. char size to (x, y) = (0.19, 0.27) cm */
-
- else /* 7470 and 7475 plotter modes */
- cs.cscale_mode = 1; /* select relative char size scaling */
- /* set relative char size to (x,y) = (0.75, 1.50) */
-
- recalc_csize ();
-
- calc_ticksize (DEF_TICK, DEF_TICK); /* set default tick size */
-
- extra_space (0.0, 0.0); /* turn off extra spacing in char strings */
-
- /* ******** NOTE ********* */
- /* HPGL/2 defaults to the maximum hard clip limits after IN; or IP; */
-
- x1 = p1x;
- x2 = p2x;
- y1 = p1y;
- y2 = p2y;
-
- if (p1x > p2x) /* correct scaling for mirrored x-axis */
- { /* need to do this only when turning */
- x1 = p2x; /* scaling off and using P1/P2 values */
- x2 = p1x; /* for scaling coordinates */
- }
-
- if (p1y > p2y) /* correct scaling for mirrored y-axis */
- {
- y1 = p2y;
- y2 = p1y;
- }
-
- /* now, turn off user scaling */
-
- scaling = OFF;
-
- set_window (x1, x2, y1, y2);
-
- endlabel = ETX;
- chord_angle = DEF_CHORD; /* chord angle default */
- DB (printf ("default parameters now set\n");)
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void default_coords ( void )
- {
-
- /* Initialize sets the default viewport */
- p1x = ip1x;
- p1y = ip1y;
- p2x = ip2x;
- p2y = ip2y; /* default corner positions */
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void set_aspect_ratio ( void )
- {
- double xmax, ymax, x_1, y_1, x_2, y_2, tmp;
-
- DB (printf ("setting aspect ratio\n");)
- if (X_mm / Y_mm > ipxsize / ipysize) /* is screen aspect ratio > aspect ratio of paper? */
- { /* adjust limit () for correct aspect ratio */
- ymax = Y_mm; /* ymax = y screen size */
- xmax = Y_mm * (ipxsize / ipysize); /* xmax = x screen size */
- gdu_cm = 1000.0 / Y_mm; /* GDU's/cm: 100 * 10 mm / cm's */
- }
- else /* aspect ratio < 11:8.5 */
- {
- xmax = X_mm; /* xmax = x screen size */
- ymax = X_mm / (ipxsize / ipysize); /* ymax = y screen size */
- gdu_cm = 1000.0 / X_mm; /* GDU's/cm: 100 * 10 mm / cm's */
- }
-
- /* set hard clip limits for correct aspect ratio */
-
- DB (printf ("xmax = %lf, ymax = %lf\n", xmax, ymax);)
-
- limit (0.0, xmax, 0.0, ymax);
-
- x_1 = p1x;
- x_2 = p2x;
- y_1 = p1y;
- y_2 = p2y;
-
- if (p1x > p2x)
- {
- tmp = x_1; /* swap scale corners */
- x_1 = x_2; /* need to do this only when turning */
- x_2 = tmp; /* scaling off and using P1/P2 values */
- } /* for scaling coordinates */
-
- if (p1y > p2y)
- {
- tmp = y_1; /* swap scale corners */
- y_1 = y_2;
- y_2 = tmp;
- }
-
- set_window (x_1, x_2, y_1, y_2);
-
-
- clip_xmin = p1x;
- clip_xmax = p2x;
- clip_ymin = p1y;
- clip_ymax = p2y; /* save hard clip border for IW instr. with scaling OFF */
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void iwindow (FILE *infile)
- {
- double x_1, x_2, y_1, y_2, tmp;
-
- if ( !get_val (infile, &x_1) ) /* no argument */
- {
- DB (printf ("IW; Clipping off\n");)
- i_window = OFF;
- if (scaling == ON) /* clip border depends on scaling */
- {
- x_1 = uux1; /* clipping border for scaled windows */
- x_2 = uux2; /* normally axis mirroring is corrected */
- y_1 = uuy1; /* in set_window () */
- y_2 = uuy2;
-
- DB (printf ("IW: (x1,y1) = (%lf, %lf), (x2, y2) = (%lf, %lf)\n", x_1, y_1, x_2, y_2);)
- set_clip (x_1, x_2, y_1, y_2);
- }
- else
- /* hard clip borders already swapped in set_aspect_ratio ()
- for case of P1 > P2. Normally, clipping is set in set_scale (),
- and the border swapping is done there */
-
- {
- DB (printf ("IW: (c_xmin,c_ymin) = (%lf, %lf), (c_xmax, c_ymax) = (%lf, %lf)\n",
- clip_xmin, clip_ymin, clip_xmax, clip_ymax);)
- set_clip (clip_xmin, clip_xmax, clip_ymin, clip_ymax);
- }
- return;
- }
- if ( !get_val (infile, &y_1) )
- {
- print_string ("Error: expecting y1 from IW instruction\n");
- return;
- }
- if ( !get_xy (infile, &x_2, &y_2) )
- {
- print_string ("IW: missing x2 or y2 argument\n");
- return;
- }
-
- if (x_1 == x_2 || y_1 == y_2)
- {
- print_string ("Error: zero range in X or Y in SC instruction\n");
- return;
- }
-
- iwx1 = x_1;
- iwx2 = x_2;
- iwy1 = y_1;
- iwy2 = y_2; /* save clipping window values */
-
- i_window = ON;
- DB (printf ("IW: (x_1, y_1) = (%lf, %lf), (x_2, y_2) = (%lf, %lf)\n", x_1, y_1, x_2, y_2);)
- set_clip (x_1, x_2, y_1, y_2); /* turn on soft clipping at specified window */
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void scale (FILE *infile)
- {
- double x_1, x_2, y_1, y_2, type;
- double fx, fy, x, y;
-
- DB (printf ("SC\n");)
- if ( !get_val (infile, &x_1) ) /* no argument */
- {
- DB (printf ("SC; scaling off\n");)
- /* turn off scaling: revert to default units */
- x_1 = p1x;
- x_2 = p2x;
- y_1 = p1y;
- y_2 = p2y;
-
- if (p1x > p2x) /* correct scaling for mirrored x-axis */
- { /* need to do this only when turning */
- x_1 = p2x; /* scaling off and using P1/P2 values */
- x_2 = p1x; /* for scaling coordinates */
- }
-
- if (p1y > p2y) /* correct scaling for mirrored y-axis */
- {
- y_1 = p2y;
- y_2 = p1y;
- }
-
- /* now, turn off user scaling */
-
- scaling = OFF;
-
- scaling = OFF;
- DB (printf ("SC; scale off: (x_1, y_1) = (%lf, %lf), (x_2, y_2) = (%lf, %lf)\n", x_1, y_1, x_2, y_2);)
- set_window (x_1, x_2, y_1, y_2); /* scaling is now in plotter units */
- return; /* anchor and hatch codes are already in plotter units */
- /* no reason for special routines to "freeze" them */
- }
- if ( !get_val (infile, &x_2) )
- {
- print_string ("Error: expecting x_2 from SC instruction\n");
- return;
- }
- if ( !get_xy (infile, &y_1, &y_2) )
- {
- print_string ("SC: missing y1 or y2 argument\n");
- return;
- }
- type = 0.0; /* type value will not change if get_val () fails */
- /* default is anisotropic scaling if */
- (void) get_val (infile, &type); /* check for type parameter */
- switch ( (int) type)
- {
- case 0:
- DB (printf ("SC: type 0: (x_1,y_1) = (%lf, %lf), (x_2,y_2) = (%lf, %lf)\n", x_1, y_1, x_2, y_2);)
-
- if (x_1 == x_2 || y_1 == y_2)
- {
- print_string ("Error: zero range in X or Y in SC instruction\n");
- return;
- }
-
- scaling = ON;
- set_window (x_1, x_2, y_1, y_2);
- scale_type = ANISOTROPIC; /* remember type of scaling */
- break;
-
- case 1: /* isotropic scaling */
- x = y = 50.0; /* centered, isotropic scaling */
- if ( get_val (infile, &x) ) /* check for left param (%) */
- {
- if ( !get_val (infile, &y) ) /* have left param: check for bottom param (%) */
- {
- print_string ("Error: expecting bottom argument from SC instruction\n");
- return;
- }
- }
-
- /* we have a type 1 (isotropic) SC instruction */
- /* if we have user supplied left and bottom params, use them */
- /* otherwise, use the default value of 50.0 for both */
- /* x, y = anchor parameters (left, bottom, resp.) */
- DB (printf ("SC: type 1: (x_1,y_1) = (%lf, %lf), (x_2,y_2) = (%lf, %lf)\n", x_1, y_1, x_2, y_2);)
- DB (printf ("SC: type 1: left = %lf, bottom = %lf\n", x, y);)
- if (x_1 == x_2 || y_1 == y_2)
- {
- print_string ("Error: zero range in X or Y in SC instruction\n");
- return;
- }
-
- /* calculate corner coordinates required because we have to offset the
- window based upon the left- and bottom-parameters */
-
- x = MIN (100.0, MAX (x, 0.0)) / 100.0;
- y = MIN (100.0, MAX (y, 0.0)) / 100.0; /* limit left & bottom to 0 -- 100% */
-
- /* Note that, although we had to swap P1 & P2 when we turned off
- user scaling when P1 > P2, we do not need to do so here. This routine
- depends on the ratio of the corner points, and, thus, is sign independent. */
-
- if (fabs ( (fx = (p2x - p1x) / (x_2 - x_1))) > fabs ( (fy = (p2y - p1y) / (y_2 - y_1))) )
- { /* rescale x-parameters */
- x_1 = x_1 - ((p2x - p1x) / fy - (x_2 - x_1)) * x;
- x_2 = x_1 + (p2x - p1x) / fy;
- }
- else
- { /* rescale y-parameters */
- y_1 = y_1 - ((p2y - p1y) / fx - (y_2 - y_1)) * y;
- y_2 = y_1 + (p2y - p1y) / fx;
- }
- scaling = ON;
- scale_type = ISOTROPIC; /* use anisotropic scaling function for correct */
- /* aspect ratio if P1 or P2 change */
- set_window (x_1, x_2, y_1, y_2);
- break;
- case 2: /* point & factor scaling */
- if (x_2 == 0.0 || y_2 == 0.0)
- {
- print_string ("Error: x-factor or y-factor in type-2 SC instruction is zero\n");
- return;
- }
- /* Convert from scaling factor to P2 coordinate for window function */
- /* Here, we have to account for the possibility that P2 < P1. The user
- must not have to alter his thinking about scaling to accomodate this.
- Therefore, we use fabs () to eliminate the sign of P2 - P1, in order to
- prevent the case of P1 > P2 from requiring the user to think in mirrored
- coordinate systems */
-
- x_2 = x_1 + fabs (p2x - p1x) / x_2;
- y_2 = y_1 + fabs (p2y - p1y) / y_2;
-
- DB (printf ("SC: type 2: (x_1,y_1) = (%lf, %lf), (x_2,y_2) = (%lf, %lf)\n", x_1, y_1, x_2, y_2);)
-
- scaling = ON;
- scale_type = ANISOTROPIC; /* remember type of scaling */
- set_window (x_1, x_2, y_1, y_2);
- break;
- default:
- printf ("Error: illegal arguments to type %1.1d SC instruction\n", (int) type);
- return;
- }
-
- uux1 = x_1;
- uux2 = x_2;
- uuy1 = y_1;
- uuy2 = y_2; /* save user scaling values */
-
- fix_anchor (); /* move anchor corner (plotter units) for new scale */ fix_hatch (); /* change size of hatch (in plotter units) for new scale */
- return;
- }
-
- /*--------------------------------------*/
-
- static void select_pen (FILE * infile, int max_pens)
- {
- double x;
-
- if ( !get_val ( infile, &x ))
- p = 0;
- else /* pen value: must limit to valid ranges */
- p = MAX ( MIN ( (int) x, max_pens), 0);
- pen ( (my_pen = pen_map[p]) );
- DB (printf ("SP: %d, internal pen = %d\n", p, my_pen);)
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void plot_line (FILE *infile, int type) /* type 1 => relative; type 0 => absolute */
- {
- double xp, yp, x_1, y_1; /* local variables */
-
- DB (if (type) printf ("PR\n"); else printf ("PA\n");)
- if (get_val (infile, &xp)) /* get x values */
- {
- if ( !get_val (infile, &yp)) /* get y value */
- {
- if (type)
- print_string ("PR: missing value\n");
- else
- print_string ("PA: missing value\n");
- return;
- }
- DB (printf ("%s: (%lf, %lf), pen status = %d;\n", (type) ? "PR" : "PA", xp, yp, p_status);)
-
- plotmode = (type) ? PR : PA;
- plotted_on (1); /* we drew something on this plot */
- do
- {
- if (type) /* relative plotting */
- {
- where (&x_1, &y_1); /* get current position */
- DB (printf ("PR: current location: (%lf, %lf)\n", x_1, y_1);)
- xp += x_1;
- yp += y_1; /* relative position */
- }
- if (!p_status == PENDOWN)
- move (xp, yp);
- else
- draw (xp, yp); /* actual drawing depends on pen being up or down */
-
- where (&x_1, &y_1); /* get current position */
- DB (printf ("now at: (%lf, %lf)\n", x_1, y_1);)
-
- cp.x = x_1;
- cp.y = y_1; /* update (x,y) for char plot fn. */
-
- if (symbol_mode)
- {
- symbol_mark (symbol);
- move (xp, yp);
- }
- }
- while (get_xy (infile, &xp,&yp));
- return;
- }
- plotmode = (type) ? PR : PA;
- DB (if (type) printf ("PR: plotting mode: relative\n"); else
- printf ("PA: plotting mode: absolute\n");)
- return;
- }
-
- /*--------------------------------------*/
-
- static void pen_down (FILE *infile)
- {
- double xp, yp, x_1, y_1; /* local variables */
-
- DB (printf ("PD\n");)
- p_status = PENDOWN; /* pen is down */
- if (get_val (infile, &xp)) /* get x values */
- {
- if ( !get_val (infile, &yp)) /* get y value */
- {
- print_string ("PD: missing y-value\n");
- return;
- }
- plotted_on (1); /* we drew something on this plot */
- do
- {
- DB (printf ("PD: plot to (%lf, %lf)\n", xp, yp);)
- if (plotmode == PR)
- {
- where (&x_1, &y_1);
- DB (printf ("PD: current location: (%lf, %lf)\n", x_1, y_1);)
- xp += x_1;
- yp += y_1; /* new position relative to last */
- }
- draw (xp, yp);
-
- cp.x = xp;
- cp.y = yp; /* update (x,y) for char plot fn. */
-
- if (symbol_mode)
- {
- symbol_mark (symbol);
- move (xp, yp);
- }
- }
- while (get_xy (infile, &xp, &yp));
- }
- return;
- }
-
- /*--------------------------------------*/
-
- static void pen_up (FILE *infile)
- {
- double xp, yp, x_1, y_1; /* local variables */
-
- DB (printf ("PU\n");)
- p_status = PENUP;
- if (get_val (infile, &xp)) /* get x values */
- {
- if ( !get_val (infile, &yp)) /* get y value */
- {
- print_string ("PU: missing y-value\n");
- return;
- }
- do
- {
- DB (printf ("PU: (x,y) = (%lf, %lf)\n", xp, yp);)
- if (plotmode == PR)
- {
- where (&x_1, &y_1); /* current location */
- DB (printf ("PU: current location: (%lf, %lf)\n", x_1, y_1);)
- xp += x_1;
- yp += y_1;
- }
- move (xp, yp);
-
- cp.x = xp;
- cp.y = yp; /* update (x,y) for char plot fn. */
-
- if (symbol_mode)
- {
- symbol_mark (symbol);
- move (xp, yp);
- }
- DB (printf ("PU: move to (%lf, %lf)\n", xp, yp);)
- }
- while (get_xy (infile, &xp, &yp));
- }
- return;
- }
-
- /*--------------------------------------*/
-
- static void input_p1p2 (FILE *infile, int type)
- { /* type = 0 -> absolute coordinates, type = 1 -> relative coordinates */
- double old_p1x, old_p1y, x_1, x_2, y_1, y_2;
-
- DB ( if (type) printf ("IR\n"); else printf ("IP\n");)
- old_p1x = p1x;
- old_p1y = p1y; /* save for use in case of only P1 specified */
- if ( !get_val (infile, &x_1)) /* no arguments: use default sizes */
- {
- default_coords (); /* no arguments: use default corner positions */
-
- set_aspect_ratio (); /* scale current window */
- recalc_csize (); /* adjust char size for new P1/P2 */
- recalc_ticksize (); /* adjust tick size for new P1/P2 */
-
- return;
- }
- else
- {
- if ( !get_val (infile, &y_1)) /* get y value */
- {
- return; /* error: no p1y coordinate */
- }
- DB (printf ("IP: P1 = (%lf, %lf)\n", x_1, y_1);)
- }
-
- if (get_val (infile, &x_2))
- {
- if (!get_val (infile, &y_2))
- {
- if (type)
- printf ("IR: missing P2 y-value\n");
- else
- print_string ("IP: missing P2 y-value\n");
- return;
- }
- if (type) /* IR */
- { /* set P1/P1 as a percentage of the hardclip limits */
- p1x = x_1 * (ipxmax - ipxmin) / 100.0 + ipxmin;
- p1y = y_1 * (ipymax - ipymin) / 100.0 + ipymin;
- p2x = x_2 * (ipxmax - ipxmin) / 100.0 + ipxmin;
- p2y = y_2 * (ipymax - ipymin) / 100.0 + ipymin;
- }
- else
- {
- p1x = x_1;
- p1y = y_1;
- p2x = x_2;
- p2y = y_2;
- }
- DB (if (type) printf ("IR: P2 = (%lf, %lf)\n", x_2, y_2);
- else printf ("IP: P2 = (%lf,%lf)\n", x_2, y_2);)
- }
- else
- {
- /* only P1 specified */
- if (type) /* IR */
- { /* P1 specified as a percent of hardclip size */
- p1x = x_1 * (ipxmax - ipxmin) / 100.0 + ipxmin;
- p1y = y_1 * (ipymax - ipymin) / 100.0 + ipymin;
- }
- else /* IP */
- {
- p1x = x_1;
- p1y = y_1;
- }
- p2x += (p1x - old_p1x);
- p2y += (p1y - old_p1y); /* adjusted P2 s/t distance between P1 & P2 is constant */
- }
-
- set_aspect_ratio (); /* recalculates scale w/ new P1/P2 */
- recalc_csize ();
- recalc_ticksize ();
-
- return;
- }
-
- /*--------------------------------------*/
-
- void set_scale (double x1, double x2, double y1, double y2)
- {
- double dipx, dipy, dpx, dpy, dux, duy, xt, yt, xp1, xp2, yp1, yp2;
- double xo, yo, tmp;
-
- /* new scaling program. Does not change hardclip limits. Only changes
- soft clip window. Rescales parameters s/t user may specify hard clip
- areas larger than the plotting medium (sheet size), scale those areas,
- and display only those areas which fall within the size of the plotting
- medium */
-
- DB (printf ("set_scale: input: (x1, y1) = (%lf, %lf), (x2, y2) = (%lf, %lf)\n", x1, y1, x2, y2);)
-
- dpx = ipxmax - ipxmin;
- dpy = ipymax - ipymin; /* delta P1/P2 (x,y) for full sheet */
- dipx = p2x - p1x;
- dipy = p2y - p1y; /* delta P1/P2 (x,y) for user P1/P2 */
-
- if (dipx == 0.0) dipx = 1.0; /* force minimum size plotting area */
- if (dipy == 0.0) dipy = 1.0;
-
- dux = x2 - x1;
- duy = y2 - y1; /* size of user scaled area */
-
- xt = dpx * dux / dipx; /* total # of x user units in hard clip window */
- xo = (p1x - ipxmin) * dux / dipx; /* user units x-offset to start of hard clip window */
- xp1 = x1 - xo; /* new user unit xmin */
- xp2 = xp1 + xt; /* new user unit xmax */
-
- yt = dpy * duy / dipy; /* total # of y user units in hard clip window */
- yo = (p1y - ipymin) * duy / dipy; /* user unit y-offset to start of hard clip window */
- yp1 = y1 - yo; /* new user unit ymin */
- yp2 = yp1 + yt; /* new user unit ymax */
-
- uu_2_pux = xt / dpx; /* user units per plotter unit */
- uu_2_puy = yt / dpy; /* note that this fails when isotropic scaling is used */
-
-
- DB (printf ("set_scale: xt = %lf, yt = %lf\n", xt, yt);)
- DB (printf ("set_scale: (xp1, yp1) = (%lf, %lf), (xp2, yp2) = (%lf, %lf)\n", xp1, yp1, xp2, yp2);)
- DB (printf ("set_scale: (x1, y1) = (%lf, %lf), (x2, y2) = (%lf, %lf)\n", x1, y1, x2, y2);)
-
- uu_wincorner.x1 = x1; /* save user unit window corners for */
- uu_wincorner.x2 = x2; /* plotter_units () and user_units () */
- uu_wincorner.y1 = y1;
- uu_wincorner.y2 = y2;
-
- window (xp1, xp2, yp1, yp2); /* call the real anisotropic scaling function */
-
- xp1 = iwx1;
- xp2 = iwx2;
- yp1 = iwy1;
- yp2 = iwy2; /* copy iw values to corner coordinates */
-
- if (p1x > p2x) /* mirror x-axis */
- {
- uu_2_pux = - uu_2_pux; /* correct for P1/P2 exchange */
- }
-
- if (p1y > p2y) /* mirror y-axis */
- {
- uu_2_puy = - uu_2_puy; /* correct for P1/P2 exchange */
- }
-
- DB (printf ("set_scale: (iwx1, iwy1) = (%lf, %lf), (iwx2, iwy2) = (%lf, %lf)\n", xp1, yp1, xp2, yp2);)
- if (i_window == ON)
- {
- DB (printf ("set_scale: i_window is ON: using (iwx1, iwy1), (iwx2, iwy2)\n");)
- set_clip (xp1, xp2, yp1, yp2); /* soft clip at IW corners if IW is on */
- }
- else
- {
- DB (printf ("set_scale: i_window is OFF: using (x1, y1), (x2, y2)\n");)
- set_clip (x1, x2, y1, y2); /* soft clip at defined area (will be hardclip) */
- }
- DB (printf ("set_scale: exit\n");)
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void error (char c1, char c2)
- {
-
- if (debugging)
- fprintf (stderr, "%c%c -- invalid HPGL command\n", c1, c2);
-
- error_flag = 1;
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void anchor_corn (FILE *infile)
- {
- double x_1, y_1;
-
- x_1 = y_1 = 0.0; /* default to plotter origin if no values present */
- get_xy (infile, &x_1, &y_1); /* x_1, y_1 unchanged if no values present */
- set_anchor (x_1, y_1, scaling);
-
- return;
- }
-
- /*--------------------------------------*/
-
- void set_anchor (double x, double y, int mode)
- {
-
- anchor.x = x; /* set both user and plotter units same */
- anchor.y = y;
- anchor.mode = (scaling == ON) ? USERUNITS : PLOTTERUNITS;
- fix_anchor ();
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void fix_anchor ( void )
- {
-
- anchor.px = anchor.x;
- anchor.py = anchor.y;
- if (anchor.mode == USERUNITS)
- plotter_units (&anchor.px, &anchor.py);
- /* change anchor corner plotter units to reflect new scale */
-
- return;
- }
-
- /*--------------------------------------*/
-
- void get_anchor (double *x, double *y)
- {
-
- *x = anchor.px; /* return anchor corner in plotter units */
- *y = anchor.py;
- return;
- }
-
- /*--------------------------------------*/
-
- void plotter_units ( double *x, double *y)
- { /* convert user units to plotter units */
-
- DB (printf ("plotter_units: x = %lf, y = %lf, uu_2_pux = %lf, uu_2_puy = %lf\n",\
- *x, *y, uu_2_pux, uu_2_puy);)
- DB (printf ("plotter_units: uu_wincorner.x1 = %lf, uu_wincorner.y1 = %lf\n",\
- uu_wincorner.x1, uu_wincorner.y1);)
-
- /* include correction for exchanged P1/P2 */
- *x = (*x - uu_wincorner.x1) / uu_2_pux + ((p1x < p2x) ? p1x: p2x);
- *y = (*y - uu_wincorner.y1) / uu_2_puy + ((p1y < p2y) ? p1y: p2y);
-
- return;
- }
-
- /*--------------------------------------*/
-
- void user_units ( double *x, double *y)
- { /* convert user units to plotter units */
-
- *x = (*x - ((p1x < p2x) ? p1x: p2x)) * uu_2_pux + uu_wincorner.x1;
- *y = (*y - ((p1y < p2y) ? p1y: p2y)) * uu_2_puy + uu_wincorner.y1;
-
- return;
- }
-
- /*--------------------------------------*/
-
- void twait (FILE *infile, int delay)
- {
- time_t t1, t2, t3;
- double v1;
-
- if (delay < 0)
- {
- if ( !get_val (infile, &v1)) return; /* zero delay */
- t3 = (time_t) v1;
- }
- else
- t3 = (time_t) delay;
- time (&t1);
- time (&t2);
- while (difftime (t2, t1) < t3) time (&t2); /* delay */
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void plot_size (FILE * infile, int plotter)
- {
- double x, y;
-
- x = psxdef; /* set plot size to default values. These are not */
- y = psydef; /* changed if the get_val () call fails */
-
- if (get_val (infile, &x))
- {
- if (!get_val (infile, &y))
- {
- print_string ("PS: missing y-parameter\n");
- return;
- }
- }
- if ( plotted_on (0) ) return; /* can't change plot size in middle of plotting */
-
- x = MAX (0.0, x);
- y = MAX (0.0, y);
- if (x == 0.0 || y == 0.0) return; /* ignore zero length or width plot sizes */
-
- if (plotter == DRAFTPRO)
- {
- p2x = x / 2.0;
- p2y = y / 2.0;
- p1x = -p2x;
- p1y = -p2y;
- }
- else
- {
- p1x = 0.0;
- p1y = 0.0;
- p2x = x;
- p2y = y;
- }
- set_aspect_ratio ();
- set_window (p1x, p2x, p1y, p2y); /* set window scale */
- recalc_csize ();
- recalc_ticksize ();
-
- return;
- }
-
- /*--------------------------------------*/
-
- static void pe (FILE *source)
- {
- int bits, rval, abs_flag, base;
- double x, y, x_1, y_1, fract;
- unsigned char c;
-
- base = 64;
- fract = 1.0;
- abs_flag = 0; /* relative data */
-
- p_status = PENDOWN; /* 1st coordinate is always pen down */
- /* otherwise specified */
-
- while ((c = fgetc (source)) != EOF)
- {
- switch (c)
- {
- case (unsigned char) EOF: /* end of file */
- ungetc (c, source);
- return;
- case '7': /* base 32 data */
- DB (printf ("base 32 data\n");)
- base = 32;
- break;
- case ':': /* select pen */
- if (!get_peval (source, base, &rval)) return; /* check for file errors */
- pen (rval);
- DB (printf ("pen = %d\n", rval);)
- break;
- case ';': /* end of PE */
- DB (printf ("End PE\n");)
- return;
- break;
- case '<': /* pen up */
- p_status = PENUP; /* mark pen status up */
- break;
- case '=': /* absolute data */
- abs_flag = 1;
- break;
- case '>': /* fraction data */
- if (!get_peval (source, base, &bits))
- {
- print_string ("PE: missing fraction-value\n");
- return;
- }
- fract = (double) pow (2.0, (double) bits);
- break;
- default:
- if (base == 32)
- {
- if (c < 63 || c > 126)
- {
- DB (printf ("illegal base 32 character %c, 0x%d\n", c, c);)
- return; /* error exit */
- }
- }
- else
- if (c < 63 || c > 254 || (c < 191 && c > 126))
- {
- DB (printf ("illegal base 64 character %c, 0x%d\n", c, c);)
- return; /* error exit */
- }
-
- ungetc (c, source);
- if (!get_peval (source, base, &rval)) /* get x_value */
- {
- print_string ("PE: missing x-value\n");
- return;
- }
- x = (double) rval / fract;
- if (!get_peval (source, base, &rval))
- {
- print_string ("PE: missing x-value\n");
- return;
- }
- y = (double) rval / fract;
- if (!abs_flag) /* relative motion */
- {
- where (&x_1, &y_1); /* current location */
- DB (printf ("PE: current location: (%lf, %lf)\n", x_1, y_1);)
- x += x_1;
- y += y_1;
- }
-
- if (p_status == PENUP)
- move (x, y);
- else
- {
- draw (x,y);
- plotted_on (1); /* mark plot as dirty */
- }
-
- p_status = PENDOWN; /* mark pen as down */
- abs_flag = 0; /* clear abs. data flag */
- if (symbol_mode)
- { /* symbol at every vertex (?) */
- symbol_mark (symbol);
- move (x, y);
- }
- break;
- }
- }
- return;
- }
-
- /*--------------------------------------*/
-
- static int get_peval (FILE *source, int base, int *x)
- {
- int j, shift;
- unsigned char c;
- unsigned u, v;
-
- u = v = 0;
- shift = 0;
-
- while ( (c = fgetc (source)) != EOF)
- {
- DB (printf ("c = %c, 0x%d\n", c, c);)
- if (base == 32)
- {
- if (c == ';' || c < 63 || c > 126)
- {
- DB (printf ("Error decoding base 32 string: %c - illegal character\n", c);)
- return (0); /* fault return */
- }
- if (c > 94)
- {
- v = c - 95;
- if (shift < 1)
- u = v;
- else
- u |= v << shift;
- shift += 5;
- DB (printf ("base 32 u = %d\n", u);)
- j = (int) u;
- *x = (j & 1) ? ( - (j >> 1)) : j >> 1;
- return (1); /* Success */
- }
- v = c - 63;
-
- if (shift < 1)
- u = v;
- else
- u |= v << shift;
- shift += 5;
- if (shift > 15)
- {
- DB (printf ("base 32 integer overflow\n");)
- return (0); /* fault */
- }
- continue;
- }
- if (c == ';' || c < 63 || c > 254 || (c < 191 && c > 126))
- {
- DB (printf ("Error decoding base 64 string: %c - illegal character\n", c);)
- return (0); /* fault return */
- }
- if (c > 126)
- {
- v = c - 191;
-
- if (shift < 1)
- u = v;
- else
- u |= v << shift;